#pragma once
#ifndef OBJECT_MANAGER_HPP
#define OBJECT_MANAGER_HPP

#include <string>
#include <unordered_map>
#include <random>
#include <mutex>
#include <memory>
#include <typeindex>
#include <functional>

namespace HandleSystem {
    /// 对象句柄类型（整型标识符）
    using ObjectHandle = int;

    /// 类型擦除删除器（用于安全删除类型擦除后的对象）
    struct TypeErasedDeleter {
        using DeleteFunc = std::function<void(void*)>;
        DeleteFunc deleter;

        /// 创建特定类型的删除器实例
        template<typename T>
        static TypeErasedDeleter Create() {
            return {
                [](void* ptr) {
                    // 将void*转换为shared_ptr指针的指针并进行删除
                    delete static_cast<std::shared_ptr<T>*>(ptr);
                }
            };
        }

        /// 调用删除函数
        void operator()(void* ptr) const { deleter(ptr); }
    };

    /// 句柄上下文（存储对象的元数据）
    struct HandleContext {
        void* object;                       ///< 类型擦除的对象指针（实际是std::shared_ptr<T>*）
        std::string fullName;               ///< 完整对象名（格式：名称#命名空间#）
        std::shared_ptr<int> handleCount;   ///< 引用此上下文的句柄计数
        std::type_index typeIndex;          ///< 对象的类型信息
        TypeErasedDeleter deleter;          ///< 对象删除器
    };

    /// 句柄管理器全局环境（所有类型共享）
    struct HandleManagerEnv {
        std::unordered_map<ObjectHandle, HandleContext*> handleToContextMap;  ///< 句柄->上下文映射
        std::unordered_map<std::string, HandleContext*> nameToContextMap;     ///< 全名->上下文映射
        std::mutex mutex;  ///< 线程安全互斥锁
    };

    /// 对象包装器（提供类型安全访问）
    template <typename TObject>
    class Object {
    private:
        HandleManagerEnv* env;             ///< 关联的全局环境
        std::shared_ptr<TObject> object;   ///< 目标对象指针
        std::shared_ptr<int> handleCount;  ///< 关联的句柄计数器

    public:
        /// 构造函数（仅限内部使用）
        Object(HandleManagerEnv* e, std::shared_ptr<TObject> o, std::shared_ptr<int> hc) 
            : env(e), object(o), handleCount(hc) {};

        Object() = delete;  ///< 禁用默认构造

        /// 获取对象的共享指针（线程安全）
        std::shared_ptr<TObject> SharedPtr() {
            std::lock_guard<std::mutex> lock(env->mutex);
            return object;
        }

        /// 获取对象的句柄数（线程安全）
        int HandleCount() {
            std::lock_guard<std::mutex> lock(env->mutex);
            return *handleCount;
        }
    };

    /// 对象工厂接口
    template <typename T>
    class IObjectFactory {
    public:
        virtual ~IObjectFactory() = default;
        /// 创建对象（返回包装在堆上的shared_ptr）
        virtual std::shared_ptr<T>* Create() = 0;
    };

    /// 默认对象工厂（使用new构造对象）
    template <typename TObject>
    class DefaultObjectFactory : public IObjectFactory<TObject> {
    public:
        std::shared_ptr<TObject>* Create() override {
            return new std::shared_ptr<TObject>(new TObject);
        }
    };

    /// 对象句柄管理器（模板类，每个TObject类型一个实例）
    template <typename TObject, typename TFactory = DefaultObjectFactory<TObject>>
    class ObjectHandleManager {
        using ObjectPtr = std::shared_ptr<TObject>;
    private:
        HandleManagerEnv* env;      ///< 全局管理器环境
        std::random_device rd;      ///< 随机数设备
        std::mt19937 gen;           ///< 随机数生成器
        std::uniform_int_distribution<int> dist;  ///< 句柄分布范围
        const std::type_index managedType;  ///< 管理的类型信息
        TFactory defaultFactory;    ///< 默认对象工厂

        /// 生成唯一句柄（跳过0和已存在句柄）
        ObjectHandle GenerateUniqueHandle() {
            ObjectHandle handle;
            do {
                handle = dist(gen);
            } while (env->handleToContextMap.find(handle) != env->handleToContextMap.end() || handle == 0);
            return handle;
        }

        /// 验证名称合法性（禁止包含分隔符）
        bool IsValidName(const std::string& name) {
            return name.find(DELIMITER) == std::string::npos;
        }

        /// 创建完整对象名（格式：名称#类型空间#随机后缀（匿名时））
        std::string CreateFullObjectName(const std::string& objectName, const std::string& typeSpace) {
            return objectName.empty() ?
                "ANON" + std::string(1, DELIMITER) + typeSpace + std::string(1, DELIMITER) + std::to_string(dist(gen)) :
                objectName + std::string(1, DELIMITER) + typeSpace + std::string(1, DELIMITER);
        }

        /// 注册句柄到上下文（增加引用计数）
        void RegisterHandleToContext(ObjectHandle handle, HandleContext* context) {
            env->handleToContextMap[handle] = context;
            (*context->handleCount)++;
        }

        /// 创建对象上下文（调用工厂并初始化元数据）
        HandleContext* CreateObjectContext(const std::string& fullName, TFactory& factory) {
            ObjectPtr* object = factory.Create();
            return new HandleContext{
                static_cast<void*>(object),  // 存储shared_ptr的指针
                fullName,
                std::shared_ptr<int>(new int(0)),  // 初始化引用计数
                managedType,                // 记录类型
                TypeErasedDeleter::Create<TObject>()  // 类型化删除器
            };
        }

        /// 类型安全检查（确保上下文存储的type_index匹配）
        bool CheckTypeSafety(const HandleContext* ctx) {
            return ctx->typeIndex == managedType;
        }

    public:
        static constexpr char DELIMITER = '#';  ///< 名称分隔符

        /// 构造函数（需传入全局环境）
        ObjectHandleManager(HandleManagerEnv* e) 
            : env(e), gen(rd()), dist(1000, 0x7FFFFFFF), managedType(typeid(TObject)) {
        }

        ObjectHandleManager() = delete;  ///< 禁用默认构造
        ObjectHandleManager(const ObjectHandleManager&) = delete;  ///< 禁用拷贝
        ObjectHandleManager& operator=(const ObjectHandleManager&) = delete;  ///< 禁用赋值

        /// 创建对象（使用自定义工厂）
        ObjectHandle CreateObject(const std::string& objectName, const std::string& typeSpace, TFactory& factory) {
            std::lock_guard<std::mutex> lock(env->mutex);
            // 名称检查
            if (!IsValidName(objectName) || !IsValidName(typeSpace)) {
                return 0;  // 无效名称返回0句柄
            }

            std::string fullName;
            ObjectHandle handle = GenerateUniqueHandle();
            std::unordered_map<std::string, HandleContext*>::iterator it;

            // 匿名对象需确保生成唯一全名
            do {
                fullName = CreateFullObjectName(objectName, typeSpace);
                it = env->nameToContextMap.find(fullName);
            } while (objectName.empty() && it != env->nameToContextMap.end());

            HandleContext* ctx = nullptr;
            // 已存在同名对象
            if (it != env->nameToContextMap.end()) {
                ctx = it->second;
                // 类型校验失败
                if (!CheckTypeSafety(ctx)) {
                    return 0;
                }
            } 
            // 创建新对象
            else {
                ctx = CreateObjectContext(fullName, factory);
                env->nameToContextMap[fullName] = ctx;
            }
            
            // 关联句柄和上下文
            RegisterHandleToContext(handle, ctx);
            return handle;
        };

        /// 创建对象（使用默认工厂）
        ObjectHandle CreateObject(const std::string& objectName, const std::string& typeSpace) {
            return CreateObject(objectName, typeSpace, defaultFactory);
        }

        /// 通过名称打开已有对象（返回新句柄）
        ObjectHandle OpenObject(const std::string& objectName, const std::string& typeSpace) {
            std::lock_guard<std::mutex> lock(env->mutex);
            // 名称有效性检查（非空）
            if (!IsValidName(objectName) || !IsValidName(typeSpace) || objectName.empty()) {
                return 0;
            }

            // 构造标准全名（不含随机后缀）
            std::string fullName = objectName + std::string(1, DELIMITER) + typeSpace + std::string(1, DELIMITER);
            auto it = env->nameToContextMap.find(fullName);
            
            if (it != env->nameToContextMap.end()) {
                HandleContext* ctx = it->second;
                // 类型校验
                if (!CheckTypeSafety(ctx)) {
                    return 0;
                }
                // 生成新句柄并注册
                ObjectHandle handle = GenerateUniqueHandle();
                RegisterHandleToContext(handle, ctx);
                return handle;
            }
            return 0;  // 未找到对象
        };

        /// 关闭句柄（减少引用计数，计数为0时销毁对象）
        bool CloseHandle(ObjectHandle handle) {
            std::lock_guard<std::mutex> lock(env->mutex);
            auto handleIt = env->handleToContextMap.find(handle);
            if (handleIt == env->handleToContextMap.end()) {
                return false;  // 无效句柄
            }

            HandleContext* ctx = handleIt->second;
            // 类型安全检查
            if (!CheckTypeSafety(ctx)) {
                return false;
            }

            // 移除句柄映射
            env->handleToContextMap.erase(handleIt);

            // 引用计数减一，若为零则清理资源
            if (--*ctx->handleCount == 0) {
                auto nameIt = env->nameToContextMap.find(ctx->fullName);
                env->nameToContextMap.erase(nameIt);   // 移除名称映射
                ctx->deleter(ctx->object);             // 调用类型擦除删除器
                delete ctx;                            // 删除上下文
            }
            return true;
        }

        /// 通过句柄获取对象包装器
        Object<TObject> GetObject(ObjectHandle handle) {
            std::lock_guard<std::mutex> lock(env->mutex);
            auto it = env->handleToContextMap.find(handle);
            if (it == env->handleToContextMap.end()) {
                return { env, ObjectPtr(nullptr), std::shared_ptr<int>(nullptr) };  // 无效句柄返回空
            }

            HandleContext* ctx = it->second;
            if (!CheckTypeSafety(ctx)) {
                return { env, ObjectPtr(nullptr), std::shared_ptr<int>(nullptr) };  // 类型错误返回空
            }

            // 解析存储的对象指针并构造包装器
            return { 
                env, 
                *static_cast<ObjectPtr*>(ctx->object),  // 解引用得到shared_ptr<TObject>
                ctx->handleCount 
            };
        }
    };
}

#endif // OBJECT_MANAGER_HPP